<template>
  <view class="cart">
    <view class="c-header">
      <view class="h-edit">
        <view class="e-left">共计<text>{{ totalGoods }}</text>件宝贝</view>
        <view class="e-right" @click="isEdit = !isEdit">{{
          isEdit ? "完成" : "管理"
        }}</view>
      </view>
    </view>

    <view class="c-main">
      <template v-if="cartList.length">
        <view class="m-card" v-for="(item, i) in cartList" :key="i">
          <view class="card-title" @tap="goSwiCategory(item.activeId)">
            <view class="t-name">{{ item.categoryName }}</view>
            <icon class="iconfont icon">&#xe641;</icon>
          </view>
          <view v-for="(item1, i1) in item.goodsList" :key="i1">
            <uni-swipe-action>
              <uni-swipe-action-item :right-options="options" @click="deleteSelectedGoods('goodsList', item1)">
                <view class="card-content">
                  <axq-checkbox :checked="
                      item1.goodsItemsList.findIndex(
                        (item) => item.isChecked === false
                      ) === -1
                    " @change="select.fn.handleGoodsSelect($event, i, i1)" />
                  <view @tap.stop="
                      nav(`/subpackage/goods/pages/detail/index?id=${item1.id}`)
                    ">
                    <a-img-loader class="c-img" :src="item1.thumbnail" />
                    <view class="c-info">
                      <view class="i-name">{{ item1.name }}</view>
                      <view class="i-unit" :style="!item1.oldAlias && 'background: transparent'">
                        {{ item1.oldAlias || "" }}</view>
                      <view class="i-bottom">
                        <view class="b-price">
                          <text>￥</text><text>{{ item1.amount }}</text><text>起</text></view>
                        <view class="b-quantity">x{{ item1.total }}</view>
                      </view>
                    </view>
                  </view>
                </view>
              </uni-swipe-action-item>
            </uni-swipe-action>
            <uni-swipe-action v-for="(item2, i2) in item1.goodsItemsList" :key="i2">
              <uni-swipe-action-item :right-options="options" @click="deleteSelectedGoods('cartId', item2.id)">
                <view class="card-spec">
                  <view class="s-left">
                    <axq-checkbox :checked="item2.isChecked" @change="
                        select.fn.handleGoodsItemSelect($event, i, i1, i2)
                      " />
                    <view class="l-specification">
                      规格：<text>{{ item2["颜色"] }}/{{ item2["尺码"] }}</text>
                      <view v-if="item2.stock">超出当前库存，超出部分转为预售单。</view>
                    </view>
                    <view class="l-unit-price">单价:<text>￥{{ item2.amount }}</text></view>
                  </view>
                  <counter max="1e+15" min="1" :value="item2.quantity"
                    @change="counter.fn.handleChange($event, item2)" />
                </view>
              </uni-swipe-action-item>
            </uni-swipe-action>
          </view>
          <view class="card-footer">
            <view class="card-footer_quantity">
              共{{ item.goodsList.length }}种{{
                goodsListTotal[item.categoryName].quantity
              }}件</view>
            <view class="card-footer_line"></view>
            <view class="card-footer_price">￥{{
                ~~(
                  goodsListTotal[item.categoryName].amount +
                  (goodsListTotal[item.categoryName].oneThird / 3) * 70
                )
              }}</view>
          </view>
        </view>
      </template>
      <template v-else>
        <view class="m-empty">
          <image class="empty-img" :src="'empty/goods.png' | prefixOssUrl" alt="" />
          <view class="empty-tip">购物车暂无商品</view>
          <view class="to-buy" @tap="swi('/pages/category/index')">去逛逛</view>
        </view>
      </template>
    </view>

    <view class="c-footer" v-if="totalGoods">
      <view class="f-left">
        <view>
          <axq-checkbox :checked="allTotal.quantity === totalGoods" @change="select.fn.handleAddSelect" />
          <view class="l-label">全选</view>
        </view>
        <view class="l-price">
          <view class="p-number"><text>￥</text>{{ allTotal.amount | amountFormat }}</view>
          <view class="p-text">共{{ allTotal.quantity }}件/共{{ ~~allTotal.integral }}积分</view>
        </view>
      </view>

      <view class="f-right">
        <view class="r-btn" v-if="!isEdit" :style="allTotal.amount === 0 && 'opacity: .5;'"
          @tap="settleAccounts(Object.values(pickOnGoodsList))">结算</view>
        <view class="r-btn" v-else :style="
            isEdit &&
            !Object.values(pickOnGoodsList).find((item) => item.isChecked) &&
            'opacity: .5;'
          " :class="{ 'r-btn_delete': isEdit }" @tap="deleteSelectedGoods('checked', Object.values(pickOnGoodsList))">
          删除</view>
      </view>
    </view>
  </view>
</template>

<script>
  import EventBus from "@/event/index";
  import counter from "@/components/counter";
  import axqCheckbox from "@/components/checkbox";
  import {
    mapState
  } from "vuex";
  import {
    model
  } from "@/model";

  const {
    PurchanseCart
  } = model.collection;

  export default {
    components: {
      counter,
      axqCheckbox,
    },
    data() {
      return {
        isEdit: false,
        options: [{
          text: "删除",
          style: {
            backgroundColor: "#fe004f",
          },
        }, ],
        select: {
          fn: {
            // 勾选某种商品
            handleGoodsSelect: (e, index, index1) => {
              let goodsList = this.cartList[index].goodsList[index1];
              for (let item of goodsList.goodsItemsList) {
                item.isChecked = e;
              }
              this.select.fn.calcTotal();
            },
            // 勾选某件商品
            handleGoodsItemSelect: (e, index, index1, index2) => {
              let goodsList = this.cartList[index].goodsList[index1],
                item = goodsList.goodsItemsList[index2];
              item.isChecked = e;
              this.select.fn.calcTotal();
            },
            // 全选与反选
            handleAddSelect: (e) => {
              this.select.fn.calcTotal(true, e);
            },
            // 计算已选的总价和总数量
            calcTotal: (addSelect, bool) => {
              let goodsListTotal = {};
              for (let goodsItem of Object.values(this.pickOnGoodsList)) {
                let categoryName = goodsItem.categoryName;

                if (!goodsListTotal[categoryName]) {
                  goodsListTotal[categoryName] = {
                    quantity: 0,
                    amount: 0,
                    integral: 0,
                    oneThird: 0,
                  };
                }
                if (addSelect) {
                  goodsItem.isChecked = bool;
                }
                let statistics = goodsListTotal[categoryName];

                if (goodsItem.isChecked) {
                  if (
                    goodsItem.integralGiveDividend === 1 &&
                    goodsItem.integralGiveDivisor === 3
                  ) {
                    statistics.oneThird += goodsItem.quantity;
                  } else {
                    statistics.amount += goodsItem.amount * goodsItem.quantity;
                  }
                  statistics.quantity += goodsItem.quantity;

                  statistics.integral += goodsItem.integral * goodsItem.quantity;
                }
              }
              this.goodsListTotal = goodsListTotal;
            },
          },
        },
        counter: {
          fn: {
            // 某种商品规格数量增减
            handleChange: (e, item) => {
              clearTimeout(this.throttling);
              this.throttling = setTimeout(() => {
                this.cartQuantityUpdate(item.id, e);
              }, 300);
            },
          },
        },
        pickOnGoodsList: {},
        goodsListTotal: {},
        totalGoods: 0,
        goodsItemsList: [],
      };
    },
    created() {
      this.throttling = 0;
    },
    computed: {
      ...mapState("user", ["info"]),
      allTotal() {
        let total = {
          quantity: 0,
          amount: 0,
          integral: 0,
        };
        for (let item of Object.values(this.goodsListTotal)) {
          total.quantity += item.quantity;
          total.amount += item.amount + (item.oneThird / 3) * 70;
          total.integral += item.integral;
        }
        return total;
      },
      cartList() {
        let cartObj,
          cartList = [],
          totalGoods = 0;

        cartObj = this.goodsItemsList.reduce((cartObj, item) => {
          if (!item.goodsItems) {
            return cartObj;
          }
          let goodsType = item.goodsItems.goods.goodsCategory.name,
            goodsTypeId = item.goodsItems.goods.id;
          if (!cartObj[goodsType]) {
            cartObj[goodsType] = {};
          }
          if (!cartObj[goodsType][goodsTypeId]) {
            cartObj[goodsType].categoryId = item.goodsItems.goods.goodsCategory.id;
            cartObj[goodsType][goodsTypeId] = {
              id: goodsTypeId,
              categoryName: goodsType,
              amount: item.goodsItems.amountCost + item.goodsItems.amountCostAbove,
              name: item.goodsItems.goods.name,
              oldAlias: item.goodsItems.goods.oldAlias,
              thumbnail: item.goodsItems.goods.thumbnail,
              total: 0,
              goodsItemsList: [],
            };
          }

          // 每一个商品类型的总数
          cartObj[goodsType][goodsTypeId].total += item.quantity;
          // 页面头部的总宝贝数
          totalGoods += item.quantity;

          let goodsItem = {
            id: item.id,
            categoryName: goodsType,
            quantity: item.quantity,
            amount: item.goodsItems.amountCost + item.goodsItems.amountCostAbove,
            isChecked:
              !!this.pickOnGoodsList[item.id] &&
              this.pickOnGoodsList[item.id].isChecked,
            integral: item.goodsItems.integralGiveDividend /
              item.goodsItems.integralGiveDivisor,
            integralGiveDivisor: item.goodsItems.integralGiveDivisor,
            integralGiveDividend: item.goodsItems.integralGiveDividend,
            stock: item.quantity > item.goodsItems.stock,
            ...JSON.parse(item.goodsItems.specJson || "[]").reduce(
              (obj, specification) => {
                obj[specification.key] = specification.value;
                return obj;
              }, {}
            ),
          };
          this.pickOnGoodsList[item.id] = goodsItem;

          cartObj[goodsType][goodsTypeId].goodsItemsList.push(goodsItem);

          return cartObj;
        }, {});

        for (const [categoryName, goodsList] of Object.entries(cartObj)) {
          let activeId = goodsList.categoryId;
          delete goodsList.categoryId;
          cartList.push({
            categoryName,
            activeId,
            goodsList: Object.values(goodsList),
          });
        }
        this.totalGoods = totalGoods;
        this.select.fn.calcTotal();
        return cartList;
      },
    },
    watch: {
      info() {
        this.vacumUpCartList();
      },
    },
    onShow() {
      this.getCartList();
    },
    methods: {
      async getCartList() {
        const res = await PurchanseCart.sendApi("cartList", {
          data: {},
        });

        if (res.code !== 2000) {
          return;
        }

        this.goodsItemsList = this.get(res, "data", []);
      },
      // 更新商品数量
      async cartQuantityUpdate(purchanseCartId, quantity) {
        const res = await PurchanseCart.sendApi("cartQuantityUpdate", {
          params: {
            purchanseCartId,
            quantity,
          },
        });
        if (res.code === 2000) {
          this.getCartList();
        }
      },
      // 删除商品
      async cartDelete(purchanseCartIds) {
        const res = await PurchanseCart.sendApi("cartDelete", {
          params: {
            purchanseCartIds,
          },
        });
        if (res.code === 2000) {
          for (let id of purchanseCartIds.split(",")) {
            delete this.pickOnGoodsList[id];
          }
          await this.getCartList();

          if (this.isEdit) {
            this.isEdit = !!Object.keys(this.pickOnGoodsList).length;
          }
        }
      },
      // 创建订单
      async add(purchanseCartIds) {
        let res = await PurchanseCart.sendApi("add", {
          params: {
            purchanseCartIds,
          },
        });
        if (res.code === 5403) {
          this.uniShowModal(`抱歉！不可下单，请联系客服`);
          return;
        }
        if (res.code === 5404) {
          this.uniShowModal(`部分商品整在盘点中，请稍后`);
          return;
        }
        if (res.code !== 2000) {
          this.toast("订单创建失败");
          return;
        }
        this.vacumUpCartList();
        this.nav("/subpackage/order/pages/purchanse/update?pSn=" + res.data);
      },
      vacumUpCartList() {
        this.pickOnGoodsList = {};
        this.goodsItemsList = [];
      },
      deleteSelectedGoods(type, value) {
        let purchanseCartIds;
        if (type === "cartId") {
          purchanseCartIds = `${value}`;
        }

        if (type === "goodsList") {
          purchanseCartIds = value.goodsItemsList
            .map((item) => item.id)
            .join(",");
        }

        if (type === "checked") {
          purchanseCartIds = this.getPurchanseCartIds(value);
        }

        if (purchanseCartIds) {
          this.uniShowModal(`确认删除商品`, () => {
            this.cartDelete(purchanseCartIds);
          });
        }
      },
      getPurchanseCartIds(boolArr) {
        return boolArr
          .reduce((arr, item) => {
            if (item.isChecked) {
              arr.push(item.id);
              this.whetherBooking += Number(item.stock);
            }
            return arr;
          }, [])
          .join(",");
      },
      settleAccounts(boolArr) {
        this.whetherBooking = 0;
        let purchanseCartIds = this.getPurchanseCartIds(boolArr);
        if (!purchanseCartIds) {
          return;
        }
        if (this.whetherBooking) {
          this.uniShowModal("部分库存不足的商品将转为 预售订单。", () => {
            this.add(purchanseCartIds);
          });
          return;
        }
        this.add(purchanseCartIds);
      },
      goSwiCategory(activeId) {
        EventBus.categoryFirstRenderCartActiveId = +activeId;
        EventBus.$emit("paramsActiveId", +activeId);
        this.swi(`/pages/category/index`);
      },
      uniShowModal(content, callBack) {
        uni.showModal({
          cancelColor: "#999999",
          confirmColor: "#DB187C",
          content,
          success: (res) => {
            if (res.confirm) {
              callBack && callBack();
            }
          },
        });
      },
    },
  };
</script>
<style lang="less" scoped>
  .cart {
    background-color: #f8f6f7;
    min-height: 100vh;

    .c-header {
      position: fixed;
      width: 100vw;
      z-index: 99;
      background-color: #f8f6f7;

      .h-edit {
        z-index: 99;
        display: flex;
        justify-content: space-between;
        align-items: center;
        height: 90rpx;
        padding: 0 30rpx;
        border-top: 1rpx solid #f9f9f9;

        .e-left {
          font-size: 24rpx;
          color: #979797;
        }

        .e-right {
          font-size: 32rpx;
          font-weight: 500;
        }
      }
    }

    .c-main {
      display: flex;
      flex-direction: column;
      align-items: center;
      flex: 1;
      padding: 90rpx 0 200rpx;
      background-color: #f8f6f7;

      .m-card {
        width: 690rpx;
        margin-bottom: 30rpx;
        background: #fff;
        border-radius: 20rpx;

        .card-title {
          display: flex;
          align-items: center;
          width: 670rpx;
          height: 90rpx;
          padding-left: 20rpx;

          .t-name {
            height: 60rpx;
            font-weight: bold;
            font-size: 32rpx;
            font-weight: 500;
            color: #333;
            line-height: 60rpx;
          }

          .icon {
            margin: 0 0 0 6rpx;
            height: 60rpx;
            font-size: 36rpx;
            color: #999;
            line-height: 60rpx;
          }
        }

        .card-content {
          display: flex;
          align-items: center;
          padding: 38rpx 28rpx 39rpx;
          border-top: 1rpx solid #e8e8e8;

          axq-checkbox {
            position: relative;

            /deep/ .checkbox {
              &::before {
                content: "";
                position: absolute;
                left: -25%;
                top: -25%;
                width: 150%;
                height: 150%;
              }
            }
          }

          >view {
            display: flex;

            .c-img {
              flex-shrink: 0;
              width: 142rpx;
              height: 143rpx;
              margin: 0 19rpx 0 17rpx;

              /deep/ image {
                border-radius: 15rpx;
              }
            }

            .c-info {
              width: 100%;

              .i-name {
                display: -webkit-box;
                margin: 0 0 9rpx;
                height: 68rpx;
                line-height: 34rpx;
                color: #323232;
                font-size: 30rpx;
                font-weight: 500;
                overflow: hidden;
                -webkit-line-clamp: 2;
                -webkit-box-orient: vertical;
                text-overflow: ellipsis;
              }

              .i-unit {
                display: inline-block;
                width: 148rpx;
                height: 36rpx;
                font-size: 24rpx;
                font-weight: 400;
                color: #999;
                background: #f7f7f7;
                text-align: center;
                border-radius: 5rpx;
                overflow: hidden;
                text-overflow: ellipsis;
                white-space: nowrap;
              }

              .i-bottom {
                display: flex;
                justify-content: space-between;
                align-items: baseline;

                .b-price {
                  font-size: 32rpx;
                  font-weight: 800;
                  color: #fc524c;

                  >text:first-child {
                    font-size: 28rpx;
                  }

                  >text:last-child {
                    font-size: 24rpx;
                  }
                }

                .b-quantity {
                  font-size: 24rpx;
                  color: #333;
                }
              }
            }
          }
        }

        .card-spec {
          display: flex;
          justify-content: space-between;
          align-items: center;
          height: 90rpx;
          padding: 0 30rpx;
          border-top: 1rpx solid #e8e8e8;

          .s-left {
            display: flex;
            align-items: center;
            color: #323232;

            axq-checkbox {
              position: relative;

              /deep/ .checkbox {
                &::before {
                  content: "";
                  position: absolute;
                  left: -25%;
                  top: -25%;
                  width: 150%;
                  height: 150%;
                }
              }
            }

            text {
              color: #666;
            }

            .l-specification {
              position: relative;
              display: flex;
              align-items: center;
              margin-left: 22rpx;
              font-size: 26rpx;
              white-space: nowrap;

              text {
                display: block;
                margin-left: -3rpx;
                max-width: 176rpx;
                white-space: nowrap;
                overflow: hidden;
                text-overflow: ellipsis;
              }

              view {
                position: absolute;
                left: 0;
                bottom: -24rpx;
                font-size: 20rpx;
                color: #ff8800;
                white-space: nowrap;
              }
            }

            .l-unit-price {
              margin-left: 35rpx;
              font-size: 26rpx;
              white-space: nowrap;
            }
          }

          /deep/ .counter {
            border-radius: 10rpx;
            box-shadow: 0 0 0 2rpx #e8e8e8;
          }

          /deep/ .counter__value {
            width: 62rpx;
            margin: 0;
            box-shadow: 0 0 0 1rpx #e8e8e8;
          }
        }

        .card-footer {
          display: flex;
          justify-content: flex-end;
          align-items: center;
          height: 90rpx;
          padding-right: 20rpx;
          line-height: 90rpx;
          border-top: 1rpx solid #e8e8e8;

          &_quantity {
            font-size: 24rpx;
            color: #666666;
          }

          &_line {
            width: 1rpx;
            height: 30rpx;
            margin: 0 20rpx;
            background: #e2dfe2;
          }

          &_price {
            font-size: 30rpx;
            font-weight: bold;
            color: #fc524c;
          }
        }
      }

      .m-empty {
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
        height: 64vh;

        .empty-img {
          width: 155rpx;
          height: 130rpx;
        }

        .empty-tip {
          margin-top: 30rpx;
          font-size: 30rpx;
          font-weight: 400;
          color: #999;
          text-align: center;
        }

        .to-buy {
          width: 200rpx;
          height: 66rpx;
          margin-top: 50rpx;
          font-size: 32rpx;
          font-weight: 500;
          color: #fff;
          text-align: center;
          line-height: 66rpx;
          background: #db187c;
          border-radius: 33rpx;
        }
      }
    }

    .c-footer {
      position: fixed;
      bottom: 0;
      z-index: 99;
      display: flex;
      justify-content: space-between;
      align-items: center;
      width: 100vw;
      height: 120rpx;
      background: #fff;
      box-shadow: 0px -2rpx 3rpx 0px rgba(24, 24, 24, 0.05);

      .f-left {
        display: flex;
        align-items: center;

        >view:first-child {
          display: flex;
          flex-direction: column;
          align-items: center;
          margin-left: 50rpx;

          axq-checkbox {
            position: relative;

            /deep/ .checkbox {
              &::before {
                content: "";
                position: absolute;
                left: -25%;
                top: -25%;
                width: 150%;
                height: 150%;
              }
            }
          }

          .l-label {
            height: 30rpx;
            line-height: 30rpx;
            font-size: 28rpx;

            .l-text {
              font-size: 22rpx;
            }
          }
        }

        .l-price {
          margin-left: 30rpx;

          .p-number {
            font-size: 36rpx;
            font-weight: 800;
            color: #fc524c;

            text {
              font-size: 24rpx;
            }
          }

          .p-text {
            text-align: center;
            font-size: 24rpx;
            color: #666;
          }
        }
      }

      .f-right {
        display: flex;
        align-items: center;
        margin-right: 30rpx;

        .r-btn {
          width: 256rpx;
          height: 88rpx;
          text-align: center;
          line-height: 88rpx;
          background: #db187c;
          color: #fff;
          border-radius: 44rpx;

          &_delete {
            background: #fe004f;
          }
        }
      }
    }
  }
</style>